import sys
from PySide6.QtWidgets import QApplication, QWidget, QPushButton, QMenu
from PySide6.QtCore import QTimer, QPoint, QEvent
from PySide6.QtGui import QCursor, Qt

class ButtonAndMenu(QWidget):
    '''
    按钮+菜单的备选方案，用QPushButton和QMenu实现，比QToolButton麻烦
    '''
    def __init__(self):
        super().__init__()
        self.setWindowTitle("悬停选择")
        self.setGeometry(100, 100, 300, 200)
        
        # 创建按钮
        self.button = QPushButton("选择", self)
        self.button.setGeometry(50, 50, 100, 30)
        
        # 创建下拉菜单
        self.menu = QMenu(self)
        self.menu.addAction("选择文件", self.select_file)
        self.menu.addAction("选择文件夹", self.select_folder)
        
        # 初始化定时器
        self.hide_timer = QTimer()
        self.hide_timer.setSingleShot(True)
        self.hide_timer.timeout.connect(self.auto_hide_menu)
        
        # 安装事件过滤器
        self.button.installEventFilter(self)
        self.menu.installEventFilter(self)

    def eventFilter(self, watched, event):
        # 处理按钮悬停事件
        if watched == self.button:
            if event.type() == QEvent.Enter:
                self.show_menu()
            elif event.type() == QEvent.Leave:
                self.start_hide_timer()
        # 处理菜单悬停事件
        elif watched == self.menu:
            if event.type() == QEvent.Enter:
                self.hide_timer.stop()
            elif event.type() == QEvent.Leave:
                self.start_hide_timer()
        return super().eventFilter(watched, event)

    def show_menu(self):
        # 计算菜单弹出位置（按钮左下角）
        menu_pos = self.button.mapToGlobal(QPoint(0, self.button.height()))
        self.menu.popup(menu_pos)
        self.hide_timer.stop()

    def start_hide_timer(self):
        self.hide_timer.start(300)  # 300毫秒后检查隐藏

    def auto_hide_menu(self):
        # 获取当前鼠标位置
        cursor_pos = QCursor.pos()
        # 检查是否在按钮或菜单区域内
        in_button = self.button.rect().contains(self.button.mapFromGlobal(cursor_pos))
        in_menu = self.menu.rect().contains(self.menu.mapFromGlobal(cursor_pos))
        
        if not (in_button or in_menu):
            self.menu.hide()

    def select_file(self):
        print("执行选择文件操作")

    def select_folder(self):
        print("执行选择文件夹操作")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = ButtonAndMenu()
    window.show()
    sys.exit(app.exec())